/*
Proxy和Reflect
  Proxy 代理，
  Reflect  反射，反射的是Object
  相同点：两个方法都是一样的
*/
{
  //有一个供应商的一个原始的数据对象obj这，通过Proxy先生成一个对象，是映射obj的，然后做一些操作，然是最后用户访问的或者读取的是monitor这个对象，最后通过Proxy传递给obj对象
  let obj={
    time:'2017-9-22',
    name:'yuanmanxue',
    _r:123
  };
  //创建代理商  或者拦截  或者就是代理了所以属性对象读取的一个过程
  let monitor=new Proxy(obj,{
    //拦截对象属性的读取
    get(target,key){
      return target[key].replace('2017','2018')
    },
    //拦截对象设置属性
    set(target,key,value){
      if(key==='name'){
        return target[key]=value;
      }else{
        return target[key]
      }
    },
    //拦截判断是否有某个属性   key in object 操作
    has(target,key){
      if(key==='name'){
        return target[key]
      }else{
        return false
      }
    },
    //拦截 删除某个属性
    deleteProperty(target,key){
      if(key.indexOf('_')>=-1){
        delete target[key];
        return true;
      }else{
        return target[key];
      }
    },
    //拦截object.keys,Obejct.getOwnProperySymbol(),object.getOwnProperyNames
    ownKeys(target){
      return Object.keys(target).filter(item=>item!='time')
    }

  });
  console.log('get',monitor.time);//get  2018-9-22
  monitor.time='2044';
  console.log('set',monitor.time);//2018-9-22  没有被修改
  monitor.name='yyyyy';
  console.log('set',monitor);//{time: "2017-9-22", name: "yyyyy", _r: 123}
  console.log('has','name' in monitor);//true
  console.log('has','time' in monitor);//false
  delete monitor.time
  console.log('delete',monitor);// {time: "2017-9-22", name: "yyyyy", _r: 123}
  delete monitor._r;
  console.log('delete',monitor);//{name: "yyyyy"}
  console.log(Object.keys(monitor));//["name", "_r"]
}

{
  let obj={
    time:'2017-9-22',
    name:'yuanmanxue',
    _r:123
  };
  //直接使用Reflect直接获取   名称和用法和Proxy方法一样，用法也是一样的
  console.log('Reflect',Reflect.get(obj,'time'));//Reflect 2017-9-22
  Reflect.set(obj,'name','yyyyyyy')
  console.log('Reflect',obj.name);//Reflect yyyyyyy
  console.log('has',Reflect.has(obj,'name'));//has  true
}

{
  /*
  在真正的开发中，什么样的场景需要用到Proxy,Reflect
  */
  //对一些数据进行校验，数据的校验，表单验证

  function validator(target,validator){
      return new Proxy(target,{
        //备份
        _validator:validator,
        //代理
        set(target,key,value){
          if(target.hasOwnProperty(key)){
            let va=this._validator[key];
            if(!!va(value)){
              return Reflect.set(target,key,value)
            }else{
              throw Error(`不能设置 ${key} 到 ${value}`)
            }
          }else{
            throw Error(`${key} 不存在`)
          }
        },
      })
  }

  //设置一个校验选项，过滤条件
  const personValidator={
    name(val){
      return typeof val ==='string'
    },
    age(val){
      return typeof val === 'number' && val>18
    }
  }
  //有这样一个构造函数
class Person{
  constructor(name,age){
    this.name = name;
    this.age = age;
    return validator(this,personValidator)
  }
}
// 实例对象
const person=new Person('yuanmanxue',15);
console.info(person);
person.name='yyyyyy';
console.log(person);



}
